﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using FinanSoft.Entities;
using FinanSoft.BusinessLayer;
using FinanSoft.Utilities;
using System.IO;

namespace FinanSoft.PresentacionInventario
{
    public partial class frmCrearArticulo : Form
    {
        List<int> _accountIds;
        List<int> _umIds;
        List<int> _impuestosIds;
        int tipoOp; // 1 - Crear, 2 - Modificar

        private Item articuloEdit;
        private ItemStoreRoomInfo _storeInfo;


        /// <summary>
        /// Creador del form, recibe el articulo a editar
        /// </summary>
        /// <param name="_articuloEdit"></param>
        public frmCrearArticulo(Item _articuloEdit, int storeRoomId)
        {
            articuloEdit = _articuloEdit;
            _storeInfo = _articuloEdit.GetStoreRoomInfo(storeRoomId);
            tipoOp = 2;
            
            InitializeComponent();

            //Llena los combos necesarios
            llenarUM();
            llenarCuentas();

            cbInvAcc.Enabled = true;
            cbPurchasesAcc.Enabled = true;
            cbSalesAcc.Enabled = true;
            cbSalesCostAcc.Enabled = true;

            btnCargarImg.Enabled = true;

            btnLimpiar.Visible = false;

            txtCodigo.Enabled = false;
            
            //Llena los datos del articulo
            llenarDatosArticulo();
        }

        /// <summary>
        /// Crea el form sin datos, para crear un nuevo articulo
        /// </summary>
        public frmCrearArticulo()
        {
            tipoOp = 1;

            InitializeComponent();
                                  
            //Llena los combos necesarios
            llenarUM();
            llenarCuentas();

            cbInvAcc.Enabled = false;
            cbPurchasesAcc.Enabled = false;
            cbSalesAcc.Enabled = false;
            cbSalesCostAcc.Enabled = false;
            cbInvAcc.SelectedIndex = -1;
            cbPurchasesAcc.SelectedIndex = -1;
            cbSalesAcc.SelectedIndex = -1;
            cbSalesCostAcc.SelectedIndex = -1;

            btnCargarImg.Enabled = false;

            btnLimpiar.Visible = true;
            
            txtCodigo.Enabled = true;
        }

        /// <summary>
        /// Llena la ventana con los datos del artículo
        /// </summary>
        private void llenarDatosArticulo()
        {
            int accIndex;

            //Llena datos del articulo
            txtCodigo.Text = System.Convert.ToString(articuloEdit.CodArticulo);
            txtDescripcion.Text = articuloEdit.Descripción;
            txtComentarios.Text = articuloEdit.Comentario;

            //Marca el index actual para la UM


            //Marca el index actual para cada cuenta del articulo
            accIndex = _accountIds.IndexOf(_storeInfo.CuentaInventario.AccountID);
            cbInvAcc.SelectedIndex = accIndex;

            accIndex = _accountIds.IndexOf(_storeInfo.CuentaCompras.AccountID);
            cbPurchasesAcc.SelectedIndex = accIndex;

            accIndex = _accountIds.IndexOf(_storeInfo.CuentaVentas.AccountID);
            cbSalesAcc.SelectedIndex = accIndex;

            accIndex = _accountIds.IndexOf(_storeInfo.CuentaCostoVentas.AccountID);
            cbSalesCostAcc.SelectedIndex = accIndex;
        }

        /// <summary>
        /// Llena el combo con la lista de unidades de medida
        /// </summary>
        private void llenarUM()
        {
            cmbUM.Items.Clear();
            
            List<MeasurementUnit> umlist = ItemManager.GetInstance().GetMeasurementUnits();
            if (!ItemManager.GetInstance().IsError)
            {
                _umIds = new List<int>();

                for (int ele = 0; ele < umlist.Count; ele++)
                {
                    cmbUM.Items.Add(umlist[ele].nombre);
                    _umIds.Add(umlist[ele].idUnidadMedida);

                }
                if(cmbUM.Items.Count > 0)
                    cmbUM.SelectedIndex = 0;
            }
            else
            {
                MessageBox.Show(StoreRoomManager.GetInstance().ErrorMessage, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
                Close();
            }
        }
        
        /// <summary>
        /// Llena los combos de cuentas con los valores de las cuentas contables
        /// </summary>
        private void llenarCuentas()
        {
            AccountingCatalog catalog;

            cbInvAcc.Items.Clear();
            cbPurchasesAcc.Items.Clear();
            cbSalesAcc.Items.Clear();
            cbSalesCostAcc.Items.Clear();

            _accountIds = new List<int>();
            catalog = CatalogManager.GetInstance().GetAccountingCatalog();
            foreach (Account account in catalog.PrincipalAccounts)
            {
                addAccount(account);
            }

            cbInvAcc.SelectedIndex = 0;
            cbPurchasesAcc.SelectedIndex = 0;
            cbSalesAcc.SelectedIndex = 0;
            cbSalesCostAcc.SelectedIndex = 0;
        }

        /// <summary>
        /// Agrega una cuenta no titulo al combo
        /// </summary>
        /// <param name="account"></param>
        private void addAccount(Account account)
        {
            if (!account.IsTitle)
            {
                _accountIds.Add(account.AccountID);
                cbInvAcc.Items.Add(account.DisplayName);
                cbPurchasesAcc.Items.Add(account.DisplayName);
                cbSalesAcc.Items.Add(account.DisplayName);
                cbSalesCostAcc.Items.Add(account.DisplayName);
            }
            else
            {
                foreach (Account child in account.Children.Values)
                {
                    addAccount(child);
                }
            }
        }

        /// <summary>
        /// Valida que todos los campos esten llenos antes de una insercion o actualizacion
        /// </summary>
        /// <returns></returns>
        public bool ValidateFields()
        {
            if (txtCodigo.Text.Trim().Length == 0 || txtDescripcion.Text.Trim().Length == 0 || txtComentarios.Text.Trim().Length == 0 || 
                ((cmbUM.SelectedIndex == Constants.INVALID_ID|| cbInvAcc.SelectedIndex == Constants.INVALID_ID || 
                cbSalesAcc.SelectedIndex == Constants.INVALID_ID || cbPurchasesAcc.SelectedIndex == Constants.INVALID_ID || 
                cbSalesCostAcc.SelectedIndex == Constants.INVALID_ID) && tipoOp == 2))
            {
                MessageBox.Show(MessageConstants.MISSING_FIELDS, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            return true;
        }

        /// <summary>
        /// Verica los datos, crea el articulo en la bd y crea una articulo para cada bodega con sus cuentas por default
        /// </summary>
        public void CreateItem()
        {
            int idUM = _umIds[cmbUM.SelectedIndex];
            if (ValidateFields())
            {
                ItemManager.GetInstance().RegisterItem(txtCodigo.Text, txtDescripcion.Text, idUM, txtComentarios.Text);

                if (ItemManager.GetInstance().IsError)
                    MessageBox.Show(ItemManager.GetInstance().ErrorMessage, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
                else
                    MessageBox.Show(MessageConstants.ITEM_INSERTED, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
            }

        }

        /// <summary>
        /// Actualiza los valores de un item y sus cuentas en una bodega especifica
        /// </summary>
        public void UpdateItem()
        {
            int idUM = _umIds[cmbUM.SelectedIndex];
            if (ValidateFields())
            {
                ItemManager.GetInstance().UpdateItem(articuloEdit.Id, txtCodigo.Text, txtDescripcion.Text, txtComentarios.Text, idUM, _accountIds[cbSalesAcc.SelectedIndex],
                    _accountIds[cbPurchasesAcc.SelectedIndex], _accountIds[cbInvAcc.SelectedIndex], _accountIds[cbSalesCostAcc.SelectedIndex], _storeInfo.StoreRoom.Id);

                if (ItemManager.GetInstance().IsError)
                    MessageBox.Show(ItemManager.GetInstance().ErrorMessage, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
                else
                    MessageBox.Show(MessageConstants.ITEM_UPDATED, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
            }
        }

        /// <summary>
        /// Genera los cambios o insercion
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnActInfo_Click(object sender, EventArgs e)
        {
            if (ValidateFields())
            {
                if (tipoOp == 1) //Crear item
                {
                    CreateItem();
                }
                else //Editar item
                {
                    UpdateItem();
                }
            }           

        }

        public void limpiarCampos()
        {
            txtCodigo.Text = "";
            txtComentarios.Text = "";
            txtDescripcion.Text = "";
        }

        /// <summary>
        /// Cierra la ventana
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSalir_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void btnLimpiar_Click(object sender, EventArgs e)
        {
            limpiarCampos();
        }

        #region Metodos para manejo de imagenes
        /// <summary>
        /// Convierte una imagen en un arreglo de bytes
        /// </summary>
        /// <param name="img">Imagen a convertir</param>
        /// <returns>Arreglo de bytes</returns>
        public byte[] Image2Bytes(Image img)
        {
            string sTemp = Path.GetTempFileName();
            FileStream fs = new FileStream(sTemp, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            img.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
            fs.Position = 0;
            //
            int imgLength = Convert.ToInt32(fs.Length);
            byte[] bytes = new byte[imgLength];
            fs.Read(bytes, 0, imgLength);
            fs.Close();
            return bytes;
        }
        
        /// <summary>
        /// Convierte un arreglo de bytes en una imagen
        /// </summary>
        /// <param name="bytes">Arreglo de Bytes</param>
        /// <returns>Imagen convertida</returns>
        public Image Bytes2Image(byte[] bytes)
        {
            if (bytes == null) return null;
            //
            MemoryStream ms = new MemoryStream(bytes);
            Bitmap bm = null;
            try
            {
                bm = new Bitmap(ms);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
            return bm;
        }

        /// <summary>
        /// Obtiene una imagen de una ruta seleccionada por el usuario
        /// </summary>
        /// <returns></returns>
        public Image ObtenerImagen()
        {
            string pathImg;
            //Definimos los filtros de archivos a permitir, en este caso imagenes
            openfiledlg1.Filter = "Bitmap files (*.bmp)|*.bmp|Gif files (*.gif)|*.gif|JGP files (*.jpg)|*.jpg|All (*.*)|*.* |PNG (*.patito)|*.png ";
            ///Establece que filtro se mostrará por deceto en este caso, 3=jpg
            openfiledlg1.FilterIndex = 3;
            ///Esto aparece en el Nombre del archivo a seleccionar, se puede quitar no es fundamental
            openfiledlg1.FileName = "Seleccione una imagen";

            //El titulo de la Ventana....
            openfiledlg1.Title = "Imagen de un artículo";

            //El directorio que por deceto habrirá, para cada contrapleca del Path colocar \\ C:\\Fotitos\\Wizard y así sucesivamente
            openfiledlg1.InitialDirectory = "c:\\";

            /// Evalúa que si al aparecer el cuadro de dialogo la persona presionó Ok
            if (openfiledlg1.ShowDialog() == DialogResult.OK)
            {
                /// Si esto se cumple, capturamos la propiedad File Name y la guardamos en la variable Garrobito
                pathImg = openfiledlg1.FileName;
                //Por ultimo se la asignamos al PictureBox
                pictureBox8.Image = Image.FromFile(pathImg);

                //Muestra la imagen
                pictureBox3.Image = Image.FromFile(pathImg);

            }
            return pictureBox8.Image;
        }

        /// <summary>
        /// Carga una nueva imagen al articulo
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCargarImg_Click(object sender, EventArgs e)
        {

            byte[] imagenToBD = Image2Bytes(ObtenerImagen());

            //Insertar la imagen
            if (pictureBox8.Image != null)
            {
                bool result = ItemManager.GetInstance().RegisterItemImage(articuloEdit.Id, imagenToBD);                
            }

        }

        #endregion

    }
}
